﻿using System;
using System.Collections;
using System.Xml;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;
using InfoJetSoft.Service.EscapeRule;

namespace InfoJetSoft.Service.Worker
{
	
	class XSNViewFormatRefreshAfterUpdateWorker
	{
	
		//XSNViewFormatRefreshAfterUpdateWorker和XSNManifestServerNodeWorker功能类似.
		//XSNViewFormatRefreshAfterUpdateWorker主要是判断需要刷新页面的控件.
		//XSNManifestServerNodeWorker则是判断需要ValueChange的控件.
		//现在ValueChange都转换为Refresh,但是仍需要判断.
		public static void  formatRefreshAfterUpdate(View view)
		{
			string xslPrefix = view.XslPrefix;
			string xdPrefix = view.XdPrefix;
			
			ArrayList selectList = new ArrayList();
			XmlElement root = view.Doc.DocumentElement;

			//可能涉及数据过滤.
			string foreachFilter = "//" + NamespaceUtil.toFullName( xslPrefix, "for-each" );
			XmlNodeList foreachElementList = DOMUtil.selectNodes( root, foreachFilter, 0, view.NsResolver );
			foreach( XmlElement foreachElement in foreachElementList ){
				string select = foreachElement.GetAttribute( "select" );
				selectList.Add( select );
				//CID 0230 //2009.02.23 //Begin
				view.SDSInView.checkForeach( foreachElement, select );
				//CID 0230 //2009.02.23 //End
			}

			//可能涉及数据过滤.
			string applyTemplatesFilter = "//" + NamespaceUtil.toFullName( xslPrefix, "apply-templates" );
			XmlNodeList applyTemplatesElementList = DOMUtil.selectNodes( root, applyTemplatesFilter, 0, view.NsResolver );
			foreach( XmlElement applyTemplatesElement in applyTemplatesElementList )
			{
				string select = applyTemplatesElement.GetAttribute( "select" );
				selectList.Add( select );
				//CID 0230 //2009.02.23 //Begin
				view.SDSInView.checkBinding( select );
				//CID 0230 //2009.02.23 //End
			}

			//例子见PromotionTable_infojet.xsn, Html Select的数据过滤.
			string variableFilter = "//" + NamespaceUtil.toFullName( xslPrefix, "variable" );
			string foreachName = NamespaceUtil.toFullName( xslPrefix, "for-each" );
			XmlNodeList variableElementList = DOMUtil.selectNodes( root, variableFilter, 0, view.NsResolver );
			foreach( XmlElement variableElement in variableElementList )
			{
				bool filter = false;
				XmlNode next = variableElement.NextSibling;
				while( next != null )
				{
					if( next is XmlElement )
					{
						XmlElement nextElement = (XmlElement)next;
						if( nextElement.Name.Equals( foreachName ) )
						{
							string select = nextElement.GetAttribute( "select" );
							if( select.StartsWith( "$" ) )
							{
								filter = true;
							}
						}
					}
					next = next.NextSibling;
				}
				if( filter )
				{
					string select = variableElement.GetAttribute( "select" );
					selectList.Add( select );
				}
			}

			//REFRESH_MUST,REFRESH_NEED在AJAX请求中辨别.
			//REFRESH_MUST, 必须进行页面刷新.
			//REFRESH_NEED, 当必要时刷新页面.
			//在页面响应中,尤其是view xslt transform中,无法判断一个field是否参与了页面逻辑.
			//所以在这里记录到页面上.然后运行中在由infojet.js提交上来.

			string bindingFilter = "//@" + NamespaceUtil.toFullName( xdPrefix, "binding" );
			XmlNodeList bindingAttrList = DOMUtil.selectNodes( root, bindingFilter, 0, view.NsResolver );
			foreach( XmlAttribute bindingAttr in bindingAttrList ){
				string binding = bindingAttr.Value;
				//CID 0230 //2009.02.23 //Begin
				view.SDSInView.checkBinding( binding );
				//CID 0230 //2009.02.23 //End

				string bindingNodeName = ExpressionUtil.parseTargetNodeName( binding );
				//设置HTML_REFRESH_AFTER_UPDATE后,直接contiue,这里先处理MUST,后处理NEED,以防止MUST被NEED覆盖.
				//如果绑定结点涉及了[数据过滤][F],既在selectList中,那么需要RefreshAferUpdate.
				string logicTags = "";
				foreach( string select in selectList )
				{
					if( ExpressionUtil.exprContainingNode( select, bindingNodeName ) ){
						//只要发现一个可以确认使用了数据过滤.
						logicTags += JetConstant.LOGIC_TAG_FILTER;
						break;
					}
				}

				//是否是[配置][N]中要求刷新的Node,如果是人工配置需要刷新页面.
				if( XSNManifestServerNodeWorker.isConfigRefreshAfterUpdateNode( view.Manifest, bindingNodeName ) ) //如果是人工配置需要刷新页面.
				{
					logicTags += JetConstant.LOGIC_TAG_CONFIG;
				}
				//CID 0028 //2008.06.21 //Begin
				if( XSNManifestServerNodeWorker.isCFVFileAdapterSourcePathNoe( view.Manifest, bindingNodeName ) ) //如果是CFVFileAdapter的源Node.
				{
					logicTags += JetConstant.LOGIC_TAG_CONFIG;
				}
				//CID 0028 //2008.06.21 //End
				//是否有[Form Code][C]处理, 如果表单代码中没有修改其它节点,则可以不刷新页面.
				if( XSNManifestServerNodeWorker.isCodeNode( view.Manifest, bindingNodeName ) )                  //如果是有表单代码定义.
				{
					logicTags += JetConstant.LOGIC_TAG_PROGRAM;
				}
				//是否参与[规则][R]处理,如果规则中没有修改其它节点,则可以不刷新页面.
				if( XSNManifestServerNodeWorker.isRuleMatchNode( view.Manifest, bindingNodeName ) )              //如果是规则的匹配结点.
				{
					logicTags += JetConstant.LOGIC_TAG_RULE;
				}

				XmlElement parentElement = (XmlElement)bindingAttr.OwnerElement;
				//只在有LogicTags时才设置REFRESH_AFTER_UPDATE.
				if( logicTags.Length > 0 )
				{
					parentElement.SetAttribute(JetConstant.HTML_LOGIC_TAGS, logicTags);
				}
			}
		}
	}
}